//
//  PhotoPreviewController.swift
//  Created by wang tiao on 2025/4/19.
//

import Photos
import Kingfisher


let PhotoMaxImageWidth: CGFloat = 500

func MainAsync(after: TimeInterval = 0, handler: @escaping (() -> Void)) {
    if after > 0 {
        DispatchQueue.main.asyncAfter(deadline: .now() + after) {
            handler()
        }
    } else {
        if Thread.isMainThread {
            handler()
        } else {
            DispatchQueue.main.async {
                handler()
            }
        }
    }
}

class PhotoPreviewController: UIViewController {
        
    static let colItemSpacing: CGFloat = 20
    
    static let previewVCScrollNotification = Notification.Name("previewVCScrollNotification")
    
    var dataSources: [PhotoModel]
    
    var currentIndex: Int
    
    lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        
        let view = UICollectionView(frame: .zero, collectionViewLayout: layout)
        view.backgroundColor = .clear
        view.dataSource = self
        view.delegate = self
        view.isPagingEnabled = true
        view.showsHorizontalScrollIndicator = false
        view.register(PhotoPreviewCell.self, forCellWithReuseIdentifier: "PhotoPreviewCell")
        view.contentInsetAdjustmentBehavior = .never
        
        return view
    }()
    
    private var indexBeforOrientationChanged: Int
        
    private let backButton: UIButton = {
        let button = UIButton(type: .custom)
        var image = UIImage(named: "nav_close")
        button.setImage(image, for: .normal)
        return button
    }()
    
    private var isFirstAppear = true
    private var hideNavView = false
    
    private var orientation: UIInterfaceOrientation = .unknown
    let toolHeight = statusBarHeight + 50
    
    /// 是否在点击确定时候，当未选择任何照片时候，自动选择当前index的照片
    var autoSelectCurrentIfNotSelectAnyone = true
    
    override var prefersHomeIndicatorAutoHidden: Bool { true }
    
    class func showIn(_ controller: UIViewController, photos: [PhotoModel], index: Int) {
        let photoPreviewController = PhotoPreviewController(photos: photos, index: index)
        photoPreviewController.modalPresentationStyle = .fullScreen
        controller.present(photoPreviewController, animated: true)
    }
    
    init(photos: [PhotoModel], index: Int) {
        dataSources = photos
        currentIndex = min(index, photos.count - 1)
        indexBeforOrientationChanged = currentIndex
        super.init(nibName: nil, bundle: nil)
    }
    
    @available(*, unavailable)
    required init?(coder _: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        guard isFirstAppear else { return }
        isFirstAppear = false
        
        reloadCurrentCell()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        var insets = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0)
        if #available(iOS 11.0, *) {
            insets = self.view.safeAreaInsets
        }
        insets.top = max(20, insets.top)
        
        collectionView.frame = CGRect(
            x: -PhotoPreviewController.colItemSpacing / 2,
            y: 0,
            width: view.frame.width + PhotoPreviewController.colItemSpacing,
            height: view.frame.height
        )
        
        
        //        refreshBottomViewFrame()
        
        let ori = UIApplication.shared.statusBarOrientation
        if ori != orientation {
            orientation = ori
            collectionView.setContentOffset(
                CGPoint(x: (view.frame.width + PhotoPreviewController.colItemSpacing) * CGFloat(indexBeforOrientationChanged), y: 0
                       ), animated: false
            )
        }
    }
    
    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        collectionView.collectionViewLayout.invalidateLayout()
    }
    
    private func reloadCurrentCell() {
        guard let cell = collectionView.cellForItem(at: IndexPath(row: currentIndex, section: 0)) else {
            return
        }
    }
    
    private func setupUI() {
        
        view.backgroundColor = .black

        view.addSubview(collectionView)
        
        backButton.addTo(view)
        backButton.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside)
        backButton.snp.makeConstraints { make in
            make.left.equalToSuperview().offset(12)
            make.top.equalTo((navBarHeight - statusBarHeight - 40) * 0.5 + statusBarHeight)
            make.width.equalTo(40)
            make.height.equalTo(40)
        }
    }
    
    @objc private func backButtonTapped() {
        dismiss(animated: true)
    }
    
    private func resetSubviewStatusWhenDraging(enable: Bool) {
        collectionView.isScrollEnabled = enable
    }
    
    private func scrollToSelPreviewCell(_ model: PhotoModel) {
        guard let index = dataSources.lastIndex(of: model) else {
            return
        }
        collectionView.performBatchUpdates({
            self.collectionView.scrollToItem(at: IndexPath(row: index, section: 0), at: .centeredHorizontally, animated: false)
        }) { _ in
            self.indexBeforOrientationChanged = self.currentIndex
            self.reloadCurrentCell()
        }
    }
    
    private func tapPreviewCell() {
        hideNavView.toggle()
        
        let cell = collectionView.cellForItem(at: IndexPath(row: currentIndex, section: 0))
        if let cell = cell as? VideoPreviewCell, cell.isPlaying {
            hideNavView = true
        }
        
    }
    
}


// MARK: scroll view delegate

extension PhotoPreviewController {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        guard scrollView == collectionView else {
            return
        }
        
        NotificationCenter.default.post(name: PhotoPreviewController.previewVCScrollNotification, object: nil)
        let offset = scrollView.contentOffset
        var page = Int(round(offset.x / (view.bounds.width + PhotoPreviewController.colItemSpacing)))
        page = max(0, min(page, dataSources.count - 1))
        if page == currentIndex {
            return
        }
        currentIndex = page
        //        resetSubviewStatus()
        //        selPhotoPreview?.changeCurrentModel(to: dataSources[currentIndex])
    }
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        indexBeforOrientationChanged = currentIndex
        let cell = collectionView.cellForItem(at: IndexPath(row: currentIndex, section: 0))
    }
}

extension PhotoPreviewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return PhotoPreviewController.colItemSpacing
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return PhotoPreviewController.colItemSpacing
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: 0, left: PhotoPreviewController.colItemSpacing / 2, bottom: 0, right: PhotoPreviewController.colItemSpacing / 2)
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: view.frame.width, height: view.frame.height)
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return dataSources.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let model = dataSources[indexPath.row]
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoPreviewCell", for: indexPath) as! PhotoPreviewCell
        cell.singleTapBlock = { [weak self] in
            self?.tapPreviewCell()
        }
        
        cell.model = model
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        (cell as? PreviewBaseCell)?.willDisplay()
    }
    
    func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        (cell as? PreviewBaseCell)?.didEndDisplaying()
    }
    
}
 
 
 
